From c8f8d49382c498f789babfbf04cb75d0692af61e Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 7 Dec 2006 04:15:54 -0700 Subject: [PATCH] [IA64] implement free_irq_vector() paravirtualization This avoids a double free error message since dom0 isn't actually using the ia64_vector_mask. Signed-off-by: Akio Takebe --- .../arch/ia64/kernel/iosapic.c | 10 ++++++++ .../arch/ia64/kernel/irq_ia64.c | 7 ++++++ xen/arch/ia64/xen/hypercall.c | 23 +++++++++++++++++++ xen/include/public/physdev.h | 1 + 4 files changed, 41 insertions(+) diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c index d9b11edf96..5cbfa26004 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c @@ -197,6 +197,16 @@ int xen_assign_irq_vector(int irq) return irq_op.vector; } + +void xen_free_irq_vector(int vector) +{ + struct physdev_irq irq_op; + + irq_op.vector = vector; + if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op)) + printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n", + __FUNCTION__, vector); +} #endif /* XEN */ /* diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c index c5bba01228..495eb496f5 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c @@ -94,6 +94,13 @@ free_irq_vector (int vector) if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR) return; +#ifdef CONFIG_XEN + if (is_running_on_xen()) { + extern void xen_free_irq_vector(int); + xen_free_irq_vector(vector); + return; + } +#endif pos = vector - IA64_FIRST_DEVICE_VECTOR; if (!test_and_clear_bit(pos, ia64_vector_mask)) printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index 58c6a41115..15e9f5b26b 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -454,6 +454,29 @@ static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) break; } + case PHYSDEVOP_free_irq_vector: { + struct physdev_irq irq_op; + int vector; + + ret = -EFAULT; + if ( copy_from_guest(&irq_op, arg, 1) != 0 ) + break; + + ret = -EPERM; + if ( !IS_PRIV(current->domain) ) + break; + + ret = -EINVAL; + vector = irq_op.vector; + if (vector < IA64_FIRST_DEVICE_VECTOR || + vector > IA64_LAST_DEVICE_VECTOR) + break; + + free_irq_vector(vector); + ret = 0; + break; + } + default: ret = -ENOSYS; break; diff --git a/xen/include/public/physdev.h b/xen/include/public/physdev.h index 5692cee897..6f78a09fe1 100644 --- a/xen/include/public/physdev.h +++ b/xen/include/public/physdev.h @@ -152,6 +152,7 @@ DEFINE_XEN_GUEST_HANDLE(physdev_op_t); #define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read #define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write #define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector +#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector #define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi #define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared -- 2.30.2